# OpenTXL-C Version 11 production build process
# J.R. Cordy, Jan 2023

# Copyright 2023, James R. Cordy and others

# This process builds the production unchecked auto-translated C version 
# of the Txl-11 compiler/interpreter and command line tools

# WARNING: DO NOT RAISE THE C COMPILER OPTIMIZATION LEVEL ABOVE THE DEFAULT (-O) 
# when compiling TXL. TXL is a sufficiently strange program as to cause 
# most optimizing C compilers to generate incorrect code for it, or at 
# the very least to slow it down severely, at higher levels of optimization.

CC = gcc # g++
CFLAGS = -m64 -c -O -std=c99 -fno-inline -funsigned-char # -DCHECKED 
LD = gcc # g++
LDFLAGS = -m64 
LDLIBS = -lm 
RLFLAGS = -r 
EXE =

# Kind of signals (interrupt handlers) supported by your operating system.
# SIGTYPE=BSD  means Berkeley (BSD) signals, e.g. Linux, MacOS, Cygwin, MinGW, etc.
# SIGTYPE=SYS5 means System V (POSIX) signals, e.g. Solaris, IRIX, etc.
# SIGTYPE=NONE means no signal handling available at all.

SIGTYPE = NONE

# Localization

OS := $(shell (uname -s | sed 's/_.*//'))

MESSAGE = "Unrecognized platform - making TXL using gcc and no signal handling"

ifeq ($(OS), Darwin)
    MESSAGE = "Making TXL on MacOS using gcc and BSD signal handling"
    CFLAGS := $(CFLAGS) -mmacosx-version-min=10.12 
    LDFLAGS := $(LDFLAGS) -mmacosx-version-min=10.12
    SIGTYPE = BSD

else ifeq ($(OS), Linux)
    MESSAGE = "Making TXL on Linux using gcc and BSD signal handling"
    CFLAGS := $(CFLAGS) -Wno-format-truncation -Wno-format-overflow -Wno-unused-result
    SIGTYPE = BSD

else ifeq ($(OS), CYGWIN)
    MESSAGE = "Making TXL on Cygwin using gcc and BSD signal handling"
    CFLAGS := $(CFLAGS) -Wno-stringop-overread -Wno-stringop-overflow
    LDFLAGS := $(LDFLAGS) -Wl,--stack,8388608
    EXE = .exe
    SIGTYPE = BSD

else ifeq ($(OS), MSYS)
    MESSAGE = "Making TXL on Msys / MinGW using gcc and BSD signal handling"
    CFLAGS := $(CFLAGS) -Wno-stringop-overread -Wno-stringop-overflow
    LDFLAGS := $(LDFLAGS) -Wl,--stack,8388608
    EXE = .exe
    SIGTYPE = BSD

else ifeq ($(OS), MINGW64)
    MESSAGE = "Making TXL on Msys / MinGW using gcc and BSD signal handling"
    LDFLAGS := $(LDFLAGS) -Wl,--stack,8388608
    EXE = .exe
    SIGTYPE = BSD
endif

# Source groups
SUPPORTSRCS = src/support.h src/support/assert.h src/support/exceptions.h src/support/alloc.h src/support/arith.h \
    src/support/io.h src/support/strings.h src/support/trycatch.h 
COMMONSRCS =  src/charset.h src/errors.h src/idents.h src/limits.h src/locale.h src/options.h \
	src/shared.h src/symbols.h src/tokens.h src/trees.h 

# Object groups
SUPPORTOBJS = objs/io.o objs/strings.o objs/trycatch.o 
COMMONOBJS =  objs/charset.o objs/errors.o objs/idents.o objs/limits.o objs/locale.o objs/options.o \
	objs/shared.o objs/symbols.o objs/tokens.o objs/trees.o 
SACOMMONOBJS =  objs/charset.o objs/errorsa.o objs/idents.o objs/limits.o objs/locale.o objs/optionsa.o \
	objs/shared.o objs/symbols.o objs/tokens.o objs/trees.o 

# Main 

all : message alltxls distrib

message:
	@echo ""
	@echo $(MESSAGE)
	@echo ""

alltxls : thetxl thetxldb thetxlpf thetxlvm thetxlcvt thetxlapr 

# Regular versions

thetxl : bin objs objs/main.o objs/txl.o objs/boot.o objs/txltree.o objs/compdef.o objs/analyze.o objs/comprul.o \
	    objs/rules.o objs/xform.o objs/predefs.o objs/garbage.o objs/scan.o objs/parse.o objs/loadstor.o objs/unparse.o \
	    ${SUPPORTOBJS} ${COMMONOBJS} 
	${CC} ${LDFLAGS} -o bin/txl objs/main.o objs/txl.o objs/boot.o objs/txltree.o objs/compdef.o objs/analyze.o objs/comprul.o \
	    objs/rules.o objs/xform.o objs/predefs.o objs/garbage.o objs/scan.o objs/parse.o objs/loadstor.o objs/unparse.o \
	    ${SUPPORTOBJS} ${COMMONOBJS} ${LDLIBS}
	strip bin/txl${EXE}

thetxldb : bin objs objs/main.o objs/txl.o objs/boot.o objs/txltree.o objs/compdef.o objs/analyze.o objs/comprul.o \
	    objs/rules.o objs/xformdb.o objs/predefs.o objs/garbage.o objs/debug.o objs/scan.o objs/parse.o objs/loadstor.o objs/unparse.o \
	    ${SUPPORTOBJS} ${COMMONOBJS} 
	${CC} ${LDFLAGS} -o bin/txldb objs/main.o objs/txl.o objs/boot.o objs/txltree.o objs/compdef.o objs/analyze.o objs/comprul.o \
	    objs/rules.o objs/xformdb.o objs/predefs.o objs/garbage.o objs/debug.o objs/scan.o objs/parse.o objs/loadstor.o objs/unparse.o \
	    ${SUPPORTOBJS} ${COMMONOBJS} ${LDLIBS}
	strip bin/txldb${EXE}

thetxlpf : lib objs objs/main.o objs/txl.o objs/boot.o objs/txltree.o objs/compdef.o objs/analyze.o objs/comprul.o \
	    objs/rules.o objs/xformpf.o objs/predefs.o objs/garbage.o objs/scan.o objs/parsepf.o objs/loadstor.o objs/unparse.o \
	    ${SUPPORTOBJS} ${COMMONOBJS} 
	${CC} ${LDFLAGS} -o lib/txlpf.x objs/main.o objs/txl.o objs/boot.o objs/txltree.o objs/compdef.o objs/analyze.o objs/comprul.o \
	    objs/rules.o objs/xformpf.o objs/predefs.o objs/garbage.o objs/scan.o objs/parsepf.o objs/loadstor.o objs/unparse.o \
	    ${SUPPORTOBJS} ${COMMONOBJS} ${LDLIBS}
	strip lib/txlpf.x

thetxlvm : lib objs objs/main.o objs/txlsa.o objs/boot.o objs/rules.o objs/xform.o objs/predefs.o objs/garbage.o \
	    objs/loadsa.o objs/scan.o objs/parsa.o objs/unparsa.o ${SUPPORTOBJS} ${SACOMMONOBJS} 
	${LD} ${RLFLAGS} -o lib/txlvm.o objs/txlsa.o objs/boot.o objs/rules.o objs/xform.o \
	    objs/predefs.o objs/garbage.o objs/loadsa.o objs/scan.o objs/parsa.o objs/unparsa.o \
	    ${SUPPORTOBJS} ${SACOMMONOBJS} 
	cp objs/main.o lib/txlmain.o

thetxlcvt : bin/txlc lib objs objs/main.o objs/txlcvt.o ${SUPPORTOBJS}
	${CC} ${LDFLAGS} -o lib/txlcvt.x objs/main.o objs/txlcvt.o \
	    ${SUPPORTOBJS} ${LDLIBS}
	strip lib/txlcvt.x

thetxlapr : bin/txlp lib objs objs/main.o objs/txlapr.o ${SUPPORTOBJS}
	${CC} ${LDFLAGS} -o lib/txlapr.x objs/main.o objs/txlapr.o \
	    ${SUPPORTOBJS} ${LDLIBS}
	strip lib/txlapr.x

objs/main.o : ${SUPPORTSRCS} src/main.c 
	${CC} $(CFLAGS) -D${SIGTYPE} src/main.c; mv main.o objs/main.o

objs/boot.o : ${SUPPORTSRCS} ${COMMONSRCS} src/boot.c src/boot.h src/bootgrm.h 
	${CC} $(CFLAGS) -D${SIGTYPE} src/boot.c; mv boot.o objs/boot.o 

objs/locale.o : ${SUPPORTSRCS} src/locale.c src/locale.h 
	${CC} $(CFLAGS) -D${SIGTYPE} src/locale.c; mv locale.o objs/locale.o 

objs/limits.o : ${SUPPORTSRCS} ${COMMONSRCS} src/limits.c src/limits.h  
	${CC} $(CFLAGS) -D${SIGTYPE} src/limits.c; mv limits.o objs/limits.o 

objs/io.o : src/support/io.c src/support/io.h src/support/strings.h 
	${CC} $(CFLAGS) -D${SIGTYPE} src/support/io.c; mv io.o objs/io.o 

objs/strings.o : ${SUPPORTSRCS} src/support/strings.c src/support/strings.h 
	${CC} $(CFLAGS) -D${SIGTYPE} src/support/strings.c; mv strings.o objs/strings.o 

objs/trycatch.o : ${SUPPORTSRCS} src/support/trycatch.c src/support/trycatch.h 
	${CC} $(CFLAGS) -D${SIGTYPE} src/support/trycatch.c; mv trycatch.o objs/trycatch.o 

objs/charset.o : ${SUPPORTSRCS} src/charset.c src/charset.h
	${CC} $(CFLAGS) -D${SIGTYPE} src/charset.c; mv charset.o objs/charset.o 

objs/idents.o : ${SUPPORTSRCS} ${COMMONSRCS} src/idents.c src/idents.h
	${CC} $(CFLAGS) -D${SIGTYPE} src/idents.c; mv idents.o objs/idents.o 

objs/symbols.o : ${SUPPORTSRCS} ${COMMONSRCS} src/symbols.c src/symbols.h
	${CC} $(CFLAGS) -D${SIGTYPE} src/symbols.c; mv symbols.o objs/symbols.o 

objs/tokens.o : ${SUPPORTSRCS} src/tokens.c src/tokens.h src/limits.h 
	${CC} $(CFLAGS) -D${SIGTYPE} src/tokens.c; mv tokens.o objs/tokens.o 

objs/trees.o : ${SUPPORTSRCS} ${COMMONSRCS} src/trees.c src/trees.h 
	${CC} $(CFLAGS) -D${SIGTYPE} src/trees.c; mv trees.o objs/trees.o 

objs/options.o : ${SUPPORTSRCS} ${COMMONSRCS} src/options.c src/options.h 
	${CC} $(CFLAGS) -D${SIGTYPE} src/options.c; mv options.o objs/options.o 

objs/shared.o : ${SUPPORTSRCS} ${COMMONSRCS} src/shared.c src/shared.h  
	${CC} $(CFLAGS) -D${SIGTYPE} src/shared.c; mv shared.o objs/shared.o 

objs/rules.o : ${SUPPORTSRCS} ${COMMONSRCS} src/rules.c src/rules.h  
	${CC} $(CFLAGS) -D${SIGTYPE} src/rules.c; mv rules.o objs/rules.o 

objs/errors.o : ${SUPPORTSRCS} ${COMMONSRCS} src/errors.c src/errors.h src/txltree.h
	${CC} $(CFLAGS) -D${SIGTYPE} src/errors.c; mv errors.o objs/errors.o

objs/comprul.o : ${SUPPORTSRCS} ${COMMONSRCS} src/comprul.c src/comprul.h src/rules.h src/txltree.h src/scan.h src/parse.h src/unparse.h 
	${CC} ${CFLAGS} src/comprul.c; mv comprul.o objs/comprul.o

objs/compdef.o : ${SUPPORTSRCS} ${COMMONSRCS} src/compdef.c src/compdef.h src/analyze.h src/txltree.h 
	${CC} ${CFLAGS} src/compdef.c; mv compdef.o objs/compdef.o

objs/txltree.o : ${SUPPORTSRCS} ${COMMONSRCS} src/txltree.c src/txltree.h 
	${CC} ${CFLAGS} src/txltree.c; mv txltree.o objs/txltree.o

objs/analyze.o : ${SUPPORTSRCS} ${COMMONSRCS} src/analyze.c src/analyze.h
	${CC} ${CFLAGS} src/analyze.c; mv analyze.o objs/analyze.o

objs/loadstor.o : ${SUPPORTSRCS} ${COMMONSRCS} src/loadstor.c src/loadstor.h src/rules.h src/scan.h 
	${CC} ${CFLAGS} src/loadstor.c; mv loadstor.o objs/loadstor.o

objs/scan.o : ${SUPPORTSRCS} ${COMMONSRCS} src/scan.c src/scan.h 
	${CC} ${CFLAGS} src/scan.c; mv scan.o objs/scan.o

objs/parse.o : ${SUPPORTSRCS} ${COMMONSRCS} src/parse.c src/parse.h src/rules.h
	${CC} ${CFLAGS} src/parse.c; mv parse.o objs/parse.o

objs/parsepf.o : ${SUPPORTSRCS} ${COMMONSRCS} src/parse.c src/parse.h src/rules.h
	${CC} ${CFLAGS} -DPROFILER -o parsepf.o src/parse.c; mv parsepf.o objs/parsepf.o

objs/parsa.o : ${SUPPORTSRCS} ${COMMONSRCS} src/parse.c src/parse.h src/rules.h
	${CC} ${CFLAGS} -DNOCOMPILE -DSTANDALONE -o parsa.o src/parse.c; mv parsa.o objs/parsa.o

objs/txl.o : ${SUPPORTSRCS} ${COMMONSRCS} src/txl.c \
	src/boot.h src/bootgrm.h src/scan.h src/parse.h src/xform.h src/unparse.h src/loadstor.h src/compdef.h src/comprul.h 
	${CC} ${CFLAGS} src/txl.c; mv txl.o objs/txl.o

objs/xform.o : ${SUPPORTSRCS} ${COMMOMNSRCS} src/xform.c src/xform.h \
	src/rules.h src/scan.h src/parse.h src/unparse.h src/garbage.h src/predefs.h 
	${CC} ${CFLAGS} src/xform.c; mv xform.o objs/xform.o 

objs/xformpf.o : ${SUPPORTSRCS} ${COMMOMNSRCS} src/xform.c src/xform.h \
	src/rules.h src/scan.h src/parse.h src/unparse.h src/garbage.h src/predefs.h 
	${CC} ${CFLAGS} -DPROFILER -o xformpf.o src/xform.c; mv xformpf.o objs/xformpf.o

objs/xformdb.o : ${SUPPORTSRCS} ${COMMOMNSRCS} src/xform.c src/xform.h \
	src/rules.h src/scan.h src/parse.h src/unparse.h src/garbage.h src/predefs.h 
	${CC} ${CFLAGS} -DDEBUGGER -o xformdb.o src/xform.c; mv xformdb.o objs/xformdb.o 

objs/predefs.o : ${SUPPORTSRCS} ${COMMOMNSRCS} src/predefs.c src/predefs.h src/scan.h src/parse.h src/xform.h src/unparse.h 
	${CC} ${CFLAGS} src/predefs.c; mv predefs.o objs/predefs.o 

objs/garbage.o : ${SUPPORTSRCS} ${COMMOMNSRCS} src/garbage.c src/garbage.h src/rules.h src/xform.h 
	${CC} ${CFLAGS} src/garbage.c; mv garbage.o objs/garbage.o 

objs/debug.o : ${SUPPORTSRCS} ${COMMOMNSRCS} src/debug.c src/debug.h src/rules.h src/xform.h src/unparse.h
	${CC} ${CFLAGS} -DDEBUGGER -o debug.o src/debug.c; mv debug.o objs/debug.o 

objs/unparse.o : ${SUPPORTSRCS} ${COMMOMNSRCS} src/unparse.c src/unparse.h src/rules.h src/scan.h 
	${CC} ${CFLAGS} src/unparse.c; mv unparse.o objs/unparse.o

objs/txlsa.o : ${SUPPORTSRCS} ${COMMONSRCS} src/txl.c \
	src/boot.h src/bootgrm.h src/scan.h src/parse.h src/xform.h src/unparse.h src/loadstor.h src/compdef.h src/comprul.h 
	${CC} ${CFLAGS} -DNOCOMPILE -DSTANDALONE -o txlsa.o src/txl.c; mv txlsa.o objs/txlsa.o
	
objs/loadsa.o : ${SUPPORTSRCS} ${COMMONSRCS} src/loadstor.c src/loadstor.h src/rules.h src/scan.h 
	${CC} ${CFLAGS} -DNOCOMPILE -DSTANDALONE -o loadsa.o src/loadstor.c; mv loadsa.o objs/loadsa.o

objs/unparsa.o : ${SUPPORTSRCS} ${COMMOMNSRCS} src/unparse.c src/unparse.h src/rules.h src/scan.h 
	${CC} ${CFLAGS} -DNOCOMPILE -DSTANDALONE src/unparse.c; mv unparse.o objs/unparsa.o

objs/optionsa.o : ${SUPPORTSRCS} ${COMMONSRCS} src/options.c src/options.h 
	${CC} $(CFLAGS) -D${SIGTYPE} -DNOCOMPILE -DSTANDALONE -o optionsa.o src/options.c; mv optionsa.o objs/optionsa.o 

objs/errorsa.o : ${SUPPORTSRCS} ${COMMONSRCS} src/errors.c src/errors.h src/txltree.h
	${CC} $(CFLAGS) -D${SIGTYPE} -DNOCOMPILE -DSTANDALONE src/errors.c; mv errors.o objs/errorsa.o

objs/txlcvt.o : ${SUPPORTSRCS} src/txlcvt.c
	${CC} ${CFLAGS} src/txlcvt.c; mv txlcvt.o objs/txlcvt.o

objs/txlapr.o : ${SUPPORTSRCS} src/txlapr.c
	${CC} ${CFLAGS} src/txlapr.c; mv txlapr.o objs/txlapr.o

bin/txlc : src/scripts/unix/txlc
	cp src/scripts/unix/txlc bin/txlc

bin/txlp : src/scripts/unix/txlp
	cp src/scripts/unix/txlp bin/txlp

# Bootstrap

src/bootgrm.h : src/bootstrap/bootgrm.h
	pushd src/bootstrap; make; popd 
	cp src/bootstrap/bootgrm.h src/bootgrm.h

# Configure for distribution

distrib : bin lib opentxl
	@echo ""
	@echo "Configuring for distribution"
	@echo ""
	rm -rf opentxl-$(OS)
	cp bin/* opentxl/bin/
	cp lib/* opentxl/lib/
	cp -r src/installers/unix/* opentxl/
	cp LICENSE.txt opentxl/
	mv opentxl opentxl-$(OS)
	tar cfz opentxl-$(OS).tar.gz opentxl-$(OS)
	@echo ""
	@echo "Distributable binary in opentxl-$(OS).tar.gz"
	@echo ""

# Directories

objs :
	mkdir objs

bin :
	mkdir bin

lib :
	mkdir lib

opentxl :
	mkdir opentxl opentxl/bin opentxl/lib

clean :
	rm -f bin/* lib/* objs/*.o 
	rm -rf opentxl opentxl-* opentxl*.tar.gz 
	cd test/regression; make clean; cd ../..
	cd test; make clean; cd ..

